Always encode images with sRGB encoded pixels Bug: skia: Change-Id: Icb25bc21a30e88f21df5b0e267d5a3a05535e44a Reviewed-on: https://skia-review.googlesource.com/19544 Commit-Queue: Matt Sarett <msarett@google.com> Commit-Queue: Mike Klein <mtklein@chromium.org> Reviewed-by: Mike Klein <mtklein@chromium.org> (cherry picked from commit 1950e0a868774330330555a9a368992218f42240) Reviewed-on: https://skia-review.googlesource.com/19814 Reviewed-by: Matt Sarett <msarett@google.com> 
diff --git a/src/images/SkImageEncoderFns.h b/src/images/SkImageEncoderFns.h index b01f1cd..6b49b2d 100644 --- a/src/images/SkImageEncoderFns.h +++ b/src/images/SkImageEncoderFns.h 
@@ -15,6 +15,7 @@  #include "SkBitmap.h"  #include "SkColor.h"  #include "SkColorPriv.h" +#include "SkColorSpace_Base.h"  #include "SkICC.h"  #include "SkOpts.h"  #include "SkPreConfig.h" @@ -256,6 +257,7 @@  int width, int, const SkPMColor*) {  SkRasterPipeline_<256> p;  p.append(SkRasterPipeline::load_f16, (const void**) &src); + p.append(SkRasterPipeline::to_srgb);  p.append(SkRasterPipeline::store_u16_be, (void**) &dst);  p.run(0, width);  } @@ -268,6 +270,7 @@  SkRasterPipeline_<256> p;  p.append(SkRasterPipeline::load_f16, (const void**) &src);  p.append(SkRasterPipeline::unpremul); + p.append(SkRasterPipeline::to_srgb);  p.append(SkRasterPipeline::store_u16_be, (void**) &dst);  p.run(0, width);  } @@ -312,10 +315,21 @@  p.run(0, width);  }   -static inline sk_sp<SkData> icc_from_color_space(const SkColorSpace& cs) { +static inline sk_sp<SkData> icc_from_color_space(const SkImageInfo& info) { + SkColorSpace* cs = info.colorSpace(); + if (!cs) { + return nullptr; + } + + sk_sp<SkColorSpace> owned; + if (kRGBA_F16_SkColorType == info.colorType()) { + owned = as_CSB(cs)->makeSRGBGamma(); + cs = owned.get(); + } +  SkColorSpaceTransferFn fn;  SkMatrix44 toXYZD50(SkMatrix44::kUninitialized_Constructor); - if (cs.isNumericalTransferFn(&fn) && cs.toXYZD50(&toXYZD50)) { + if (cs->isNumericalTransferFn(&fn) && cs->toXYZD50(&toXYZD50)) {  return SkICC::WriteToICC(fn, toXYZD50);  }   
diff --git a/src/images/SkJpegEncoder.cpp b/src/images/SkJpegEncoder.cpp index eaea77e..a0ee398 100644 --- a/src/images/SkJpegEncoder.cpp +++ b/src/images/SkJpegEncoder.cpp 
@@ -207,29 +207,19 @@  jpeg_set_quality(encoderMgr->cinfo(), options.fQuality, TRUE);  jpeg_start_compress(encoderMgr->cinfo(), TRUE);   - if (SkColorSpace* cs = src.colorSpace()) { - sk_sp<SkColorSpace> owned; - if (src.colorType() == kRGBA_F16_SkColorType) { - // We'll be converting to 8-bit sRGB, so we'd better tag it that way. - owned = as_CSB(src.colorSpace())->makeSRGBGamma(); - cs = owned.get(); - } + sk_sp<SkData> icc = icc_from_color_space(src.info()); + if (icc) { + // Create a contiguous block of memory with the icc signature followed by the profile. + sk_sp<SkData> markerData = + SkData::MakeUninitialized(kICCMarkerHeaderSize + icc->size()); + uint8_t* ptr = (uint8_t*) markerData->writable_data(); + memcpy(ptr, kICCSig, sizeof(kICCSig)); + ptr += sizeof(kICCSig); + *ptr++ = 1; // This is the first marker. + *ptr++ = 1; // Out of one total markers. + memcpy(ptr, icc->data(), icc->size());   - sk_sp<SkData> icc = icc_from_color_space(*cs); - if (icc) { - // Create a contiguous block of memory with the icc signature followed by the profile. - sk_sp<SkData> markerData = - SkData::MakeUninitialized(kICCMarkerHeaderSize + icc->size()); - uint8_t* ptr = (uint8_t*) markerData->writable_data(); - memcpy(ptr, kICCSig, sizeof(kICCSig)); - ptr += sizeof(kICCSig); - *ptr++ = 1; // This is the first marker. - *ptr++ = 1; // Out of one total markers. - memcpy(ptr, icc->data(), icc->size()); - - jpeg_write_marker(encoderMgr->cinfo(), kICCMarker, markerData->bytes(), - markerData->size()); - } + jpeg_write_marker(encoderMgr->cinfo(), kICCMarker, markerData->bytes(), markerData->size());  }    return std::unique_ptr<SkJpegEncoder>(new SkJpegEncoder(std::move(encoderMgr), src)); 
diff --git a/src/images/SkPngEncoder.cpp b/src/images/SkPngEncoder.cpp index d28657f..7a1bfcf 100644 --- a/src/images/SkPngEncoder.cpp +++ b/src/images/SkPngEncoder.cpp 
@@ -53,7 +53,7 @@  bool setHeader(const SkImageInfo& srcInfo, const SkPngEncoder::Options& options);  bool setPalette(const SkImageInfo& srcInfo, SkColorTable* colorTable,  SkTransferFunctionBehavior); - bool setColorSpace(SkColorSpace* colorSpace); + bool setColorSpace(const SkImageInfo& info);  bool writeInfo(const SkImageInfo& srcInfo);  void chooseProc(const SkImageInfo& srcInfo, SkTransferFunctionBehavior unpremulBehavior);   @@ -327,8 +327,8 @@  return true;  }   -static void set_icc(png_structp png_ptr, png_infop info_ptr, const SkColorSpace& colorSpace) { - sk_sp<SkData> icc = icc_from_color_space(colorSpace); +static void set_icc(png_structp png_ptr, png_infop info_ptr, const SkImageInfo& info) { + sk_sp<SkData> icc = icc_from_color_space(info);  if (!icc) {  return;  } @@ -344,17 +344,15 @@  png_set_iCCP(png_ptr, info_ptr, name, 0, iccPtr, icc->size());  }   -bool SkPngEncoderMgr::setColorSpace(SkColorSpace* colorSpace) { +bool SkPngEncoderMgr::setColorSpace(const SkImageInfo& info) {  if (setjmp(png_jmpbuf(fPngPtr))) {  return false;  }   - if (colorSpace) { - if (colorSpace->isSRGB()) { - png_set_sRGB(fPngPtr, fInfoPtr, PNG_sRGB_INTENT_PERCEPTUAL); - } else { - set_icc(fPngPtr, fInfoPtr, *colorSpace); - } + if (info.colorSpace() && info.colorSpace()->isSRGB()) { + png_set_sRGB(fPngPtr, fInfoPtr, PNG_sRGB_INTENT_PERCEPTUAL); + } else { + set_icc(fPngPtr, fInfoPtr, info);  }    return true; @@ -401,7 +399,7 @@  return nullptr;  }   - if (!encoderMgr->setColorSpace(src.colorSpace())) { + if (!encoderMgr->setColorSpace(src.info())) {  return nullptr;  }   
diff --git a/src/images/SkWebpEncoder.cpp b/src/images/SkWebpEncoder.cpp index 81ed7e1..296d4f4 100644 --- a/src/images/SkWebpEncoder.cpp +++ b/src/images/SkWebpEncoder.cpp 
@@ -194,16 +194,7 @@  // If there is no need to embed an ICC profile, we write directly to the input stream.  // Otherwise, we will first encode to |tmp| and use a mux to add the ICC chunk. libwebp  // forces us to have an encoded image before we can add a profile. - sk_sp<SkData> icc; - if (SkColorSpace* cs = pixmap.colorSpace()) { - sk_sp<SkColorSpace> owned; - if (pixmap.colorType() == kRGBA_F16_SkColorType) { - // We'll be converting to 8-bit sRGB, so we'd better tag it that way. - owned = as_CSB(pixmap.colorSpace())->makeSRGBGamma(); - cs = owned.get(); - } - icc = icc_from_color_space(*cs); - } + sk_sp<SkData> icc = icc_from_color_space(pixmap.info());  SkDynamicMemoryWStream tmp;  pic.custom_ptr = icc ? (void*)&tmp : (void*)stream;